package com.rizzo.infrastructure.amqp.rabbit.log4j;

import org.apache.log4j.spi.LoggingEvent;

import java.io.Serializable;

/**
 * Created by IntelliJ IDEA.
 * User: jalie
 * Date: 10/14/12
 * Time: 11:21 AM
 * To change this template use File | Settings | File Templates.
 */
public class LogStatement implements Serializable {

    public static final String PERFORMANCE_PREFIX = "RIZZO-PERF - ";
    public static final String PRINCIPAL_MARKER_START = "[Principal:";
    public static final String PRINCIPAL_MARKER_END = "] - ";
    public static final String KEY_SEPERATOR = ":";

    public enum LogType {PERFORMANCE, STATEMENT}

    private String application;
    private String message;
    private String level;
    private String categoryName;
    private String method;
    private String principal;
    private long timestamp;
    private String duration;
    private Integer instanceIndex;
    private String instanceName;
    private LogType type = LogType.STATEMENT;

    public LogStatement() {
    }

    public LogStatement(LoggingEvent loggingEvent, String message, String application, Integer instanceIndex, String instanceName) {
        this.application = application;
        this.message = message;
        this.level = loggingEvent.getLevel().toString().toLowerCase();
        this.categoryName = loggingEvent.getLoggerName();
        this.timestamp = loggingEvent.getTimeStamp();
        this.instanceIndex = instanceIndex;
        this.instanceName = instanceName;
        if (message.contains(PERFORMANCE_PREFIX)) {
            this.type = LogType.PERFORMANCE;
            this.method = parseMethod(message);
            this.principal = parsePrincipal(message);
            this.duration = parseDuration(message);
        }
    }

    private String parsePrincipal(String message) {
        int start = message.lastIndexOf(PRINCIPAL_MARKER_START);
        int startLength = PRINCIPAL_MARKER_START.length();
        int end = message.lastIndexOf(PRINCIPAL_MARKER_END);
        if (end < 0 || start < 0) {
            return "";
        } else {
            return message.substring(start + startLength, end);
        }
    }

    private String parseMethod(String message) {
        int start = message.lastIndexOf(".");
        int end = message.lastIndexOf("': ");
        if (end < 0 || start < 0) {
            throw new IllegalArgumentException("Could not parse method out of performance logStatement's message!");
        } else {
            return message.substring(start + 1, end);
        }
    }

    private String parseDuration(String message) {
        int last = message.lastIndexOf(" = ");
        if (last < 0) {
            throw new IllegalArgumentException("Could not parse duration out of performance logStatement's message!");
        } else {
            return message.substring(last + 3);
        }

    }

    public String getApplication() {
        return application;
    }

    public String getMessage() {
        return message;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public String getLevel() {
        return level;
    }

    public String getMethod() {
        return method;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public String getDuration() {
        return duration;
    }

    public Integer getInstanceIndex() {
        return instanceIndex;
    }

    public String getInstanceName() {
        return instanceName;
    }

    public LogType getType() {
        return type;
    }

    public String getPrincipal() {
        return principal;
    }

    public void setApplication(String application) {
        this.application = application;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public void setLevel(String level) {
        this.level = level;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public void setMethod(String method) {
        this.method = method;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public void setDuration(String duration) {
        this.duration = duration;
    }

    public void setInstanceIndex(Integer instanceIndex) {
        this.instanceIndex = instanceIndex;
    }

    public void setInstanceName(String instanceName) {
        this.instanceName = instanceName;
    }

    public void setType(LogType type) {
        this.type = type;
    }

    public void setPrincipal(String principal) {
        this.principal = principal;
    }
}
